package hu.myai.indicators.pivot;

import hu.myai.api.indicators.AbstractIndicator;
import hu.myai.model.IndicatorVO;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The return value is the value of the last high. - parameter gives the
 * interval (before and after the timstamp of the tick) where the pivot is a
 * local pivot. Suggested value is 5
 * 
 * @author bozbalint
 * 
 * */
public class LastHighIndicator extends AbstractIndicator {

	/**
	 * The object used when logging debug,errors,warnings and info.
	 * */
	private final Logger log = LoggerFactory.getLogger(this.getClass());

	/**
	 * Value of the current highest tick
	 * */
	double high = Double.NEGATIVE_INFINITY;

	/**
	 * Timestamp value of the high
	 * */
	int highPos = 0;

	/**
	 * Value of the current lowest tick
	 * */
	double low = Double.POSITIVE_INFINITY;

	/**
	 * Timestamp value of the low
	 * */
	int lowPos = 0;

	/**
	 * Indicator return value
	 * */
	Double lastHigh = null;

	/**
	 * direction of the trend, to avoid unnecessary loops
	 * */
	boolean isDown = true;

	/**
	 * direction of the trend, to avoid unnecessary loops
	 * */
	boolean isUp = true;

	public LastHighIndicator(Double parameter) {
		super(parameter);
	}

	@Override
	public void init() {
	}

	@Override
	protected IndicatorVO indicatorCalculation() {

		// to check indicator change
		boolean isNewHigh = false;
		int timestamp = lastTick.getTimestamp();
		// -1 because of last is not interesting
		int ckInterval = parameter.intValue() - 1;

		// check if the new tick is higher than the current highest tick
		if (lastTick.getHigh() > high) {
			high = lastTick.getHigh();
			highPos = timestamp;
			isUp = true;
		}

		// check if the new tick is lower then the low
		if (lastTick.getHigh() < low) {
			low = lastTick.getHigh();
			lowPos = timestamp;
			isDown = true;
		}

		// no higher tick in the time interval given by the parameter
		if (isUp && timestamp - highPos > parameter - 1) {
			lastHigh = high;
			// if was a low in the turning point buffer
			low = tickHistory.get(ckInterval).getHigh();
			for (int i = 0; i < ckInterval; i++) {
				double closeItem = tickHistory.get(i).getHigh();
				if (closeItem < low) {
					low = closeItem;
					lowPos = tickHistory.get(i).getTimestamp();
					isDown = true;
				}
			}
			isUp = false;
			isNewHigh = true;
		}

		// no lower tick in the time interval given by the parameter
		if (isDown && timestamp - lowPos > parameter - 1) {
			// if was a high in the turning point buffer
			high = tickHistory.get(ckInterval).getHigh();
			for (int i = 0; i < ckInterval; i++) {
				double closeItem = tickHistory.get(i).getHigh();
				if (closeItem > high) {
					high = closeItem;
					highPos = tickHistory.get(i).getTimestamp();
					isUp = true;
				}
			}
			isDown = false;
		}

		// not enough data
		if (lastHigh == null)
			return null;

		IndicatorVO indicator = new IndicatorVO();
		indicator.setDate(lastTick.getTime());
		indicator.setValue(lastHigh);
		indicator.setChanged(isNewHigh);

		log.debug(indicator.toString());
		return indicator;
	}
}
